package cmd

import (
	"fmt"
	"github.com/CIPFZ/collector/internal/app"
	"github.com/CIPFZ/collector/internal/collectors/base"
	"github.com/CIPFZ/collector/internal/types"
	"github.com/CIPFZ/collector/pkg/exception"

	"github.com/spf13/cobra"
	"go.uber.org/zap"
)

// NewCollectCommand 创建 collect 命令
func NewCollectCommand(collector *app.Collector) *cobra.Command {
	opts := &types.CollectOptions{}

	cmd := &cobra.Command{
		Use:   "collect",
		Short: "Collect system information, logs, and execute commands",
		Long: `Collect various types of information from the system including:
- System information (CPU, memory, disk, network)
- Log files from specified sources
- Command execution results

The collection process supports real-time progress tracking and can be cancelled at any time.

Examples:
  collector collect                     # Collect all enabled modules
  collector collect --system-only       # Collect only system information
  collector collect --logs-only         # Collect only logs
  collector collect --live              # Show real-time progress
  collector collect --output ./data     # Specify output directory
  collector collect --format yaml       # Output in YAML format`,
		RunE: func(cmd *cobra.Command, args []string) error {
			logger := collector.Logger()

			if opts.TaskID == "" {
				return exception.NewNotTaskIdError("missing required flag: --task-id")
			}

			logger.Info("Starting collection process",
				zap.String("task-id", opts.TaskID),
				zap.Bool("system_only", opts.SystemOnly),
				zap.Bool("logs_only", opts.LogsOnly),
				zap.Bool("commands_only", opts.CommandsOnly),
				zap.String("output_dir", opts.OutputDir),
				zap.String("format", opts.Format),
				zap.Bool("live", opts.Live),
				zap.Bool("quiet", opts.Quiet),
			)

			// 创建收集器
			collectorBase, err := base.NewCollectorBase(collector)
			if err != nil {
				logger.Error("Failed to initialize collector",
					zap.String("task-id", opts.TaskID),
					zap.Error(err))
				return exception.NewCollectorBaseError(err)
			}

			// 开启收集任务
			_, err = collectorBase.RunCollectTask(
				collector.Context(),
				opts,
			)
			if err != nil {
				logger.Error("Failed to run collect task",
					zap.String("task-id", opts.TaskID),
					zap.Error(err))
				return exception.NewTaskExecuteError(opts.TaskID, err)
			}

			if !opts.Quiet {
				fmt.Println("\nCollection finished successfully")
			}
			logger.Info("Collection finished successfully", zap.String("task-id", opts.TaskID))
			return nil
		},
	}

	// Bind flags to CollectOptions
	cmd.Flags().StringVar(&opts.TaskID, "task-id", "", "collect task unique id")
	cmd.Flags().BoolVar(&opts.SystemOnly, "system-only", false, "collect only system information")
	cmd.Flags().BoolVar(&opts.LogsOnly, "logs-only", false, "collect only logs")
	cmd.Flags().BoolVar(&opts.CommandsOnly, "commands-only", false, "execute only commands")
	cmd.Flags().StringVar(&opts.OutputDir, "output", "", "output directory (default from config)")
	cmd.Flags().StringVar(&opts.Format, "format", "", "output format: json, yaml, csv (default from config)")
	cmd.Flags().BoolVar(&opts.Live, "live", false, "show live progress")
	cmd.Flags().BoolVar(&opts.Quiet, "quiet", false, "quiet mode, minimal output")

	return cmd
}
